package com.neuedu.common.template;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.neuedu.common.core.domain.R;

import java.util.Objects;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.ObjectProvider;

@Slf4j
public abstract class AbstractContextExecutor<Req, Context, Resp> implements ImmutableTripleConsumer<Req, Context, R<Resp>> {

    protected final ObjectMapper objectMapper;

    public AbstractContextExecutor(ObjectProvider<ObjectMapper> objectMapper) {
        this.objectMapper = objectMapper.getIfUnique();
    }

    @Override
    public void accept(Req request, Context context, R<Resp> result) throws Exception {
        if (result.isSuccess()) {
            this.operate(request, context, result);
        }
    }

    private void operate(Req request, Context context, R<Resp> result) throws Exception {
        result = this.preValidate(request, context, result);
        if (!result.isSuccess()) {
            return;
        }
        this.process(request, context, result);
        this.postValidate(request, context, result);
    }

    protected R<Resp> preValidate(Req request, Context context, R<Resp> result) {
        if (Objects.isNull(result)) {
            return R.fail("result null");
        }
        if (Objects.isNull(request)) {
            return R.fail("request null");
        }
        if (Objects.isNull(context)) {
            return R.fail("context null");
        }

        return result;
    }

    protected void postValidate(Req request, Context context, R<Resp> result) {
    }

    protected abstract void process(Req request, Context context, R<Resp> result) throws Exception;

}

